/**
    @file mainwindow.cpp
    Copyright (C) 2011  AlexK. <alexander.kaspar@gmail.com>
**/

#include <QSettings>
#include <QMessageBox>
#include <QDateTime>
#include <QFileDialog>
#include <QDialog>

#include "mainwindow.h"
#include "settingsdlg.h"
#include "_myfile.h"
#include "transfer.h"

/**
 * @brief Constructor used if no CLI Argument is given
 *
 * @param parent QWidget, QDialog
 **/
MainWindow::MainWindow ( QWidget* parent ) : QDialog ( parent ) {
    //	log("blue", "In MainWindow constructor 1 ...");
    setupUi ( this );

    SettingsFile = QDir::homePath() + "/.kifxofxrc";
    loadSettings();

    connect ( okButton, SIGNAL ( clicked() ), this, SLOT ( process() ) );
    connect ( cancelButton, SIGNAL ( clicked() ), this, SLOT ( reject() ) );
    connect ( settingsButton, SIGNAL ( clicked() ), this, SLOT ( settings() ));

    // update UI
    //allCheckBox->setChecked ( true );
    progressBar->setValue ( 0 );
}

/**
 * @brief Constructor used with Command Line Argument given
 *
 * @param fileName QString: IFX Filename given on CLI
 * @param parent QWidget, QDialog
 **/
MainWindow::MainWindow ( QString fileName, QWidget* parent ) : QDialog ( parent ) {
    //	log("blue", "In MainWindow constructor 2 ...");
    setupUi ( this );

    SettingsFile = QDir::homePath() + "/.kifxofxrc";

    // get values from standard filename (has to be: KTNR_[DDA|CCA]*.csv)
    acctid = QString(IFXFile.get_ifxbaseName(fileName).split("_").value(0));
    accttype = QString(IFXFile.get_ifxbaseName(fileName).split("_").value(1));
    loadSettings(acctid);

    bool ok;
    acctid.toInt(&ok);
    if(!ok) {
        Ui::SettingsDlg ui;
        QDialog *settingsDlg = new QDialog;
        ui.setupUi(settingsDlg);
        settingsDlg->show();
    }

    connect ( okButton, SIGNAL ( clicked() ), this, SLOT ( process() ) );
    connect ( cancelButton, SIGNAL ( clicked() ), this, SLOT ( reject() ) );
    connect ( settingsButton, SIGNAL ( clicked() ), this, SLOT ( settings(); ));

    _MyFile *IFXFile = new _MyFile();
    _MyFile *OFXFile = new _MyFile();
    ifxfile = IFXFile->get_ifxfullFileName ( fileName );
    ofxfile = OFXFile->get_ofxfullFileName ( fileName );

    //    log("blue", "ifxfile: " + ifxfile);
    //    log("blue", "ofxfile: " + ofxfile);
    //    log("blue", "SettingsFile: " + SettingsFile);

    // update UI
    ifxLineEdit->setText ( ifxfile );
    ofxLineEdit->setText ( ofxfile );
    progressBar->setValue ( 0 );
}

/**
 * @brief has ifxLineEdit Text changed?
 *
 * @return void
 **/
void MainWindow::on_ifxLineEdit_textChanged() {
    //    log("blue", "In: on_ifxLineEdit_textChanged()");

    // update UI
    okButton->setEnabled ( true );
}

/**
 * @brief is ifxOpenButton clicked?
 *
 * @return void
 **/
void MainWindow::on_ifxOpenButton_clicked() {
    //    log("blue", "In: on_ifxOpenButton_clicked()");

    if ( !allCheckBox->isChecked() ) {	// Open one File ...
        _ifxf = IFXFile.get_Handle_to_Infile ( "f", _ifxd );
        _ofxf = OFXFile.get_ofxfullFileName ( _ifxf );

        ifxLineEdit->setText ( _ifxf );
        ofxLineEdit->setText ( _ofxf );
    } else {								// Open Directory ...
        _ifxd = IFXFile.get_Handle_to_Infile ( "d", _ifxd );
        _ofxd = _ifxd + QString ( "/ofx/" );

        ifxLineEdit->setText ( _ifxd );
        ofxLineEdit->setText ( _ofxd );
    }
}

/**
 * @brief is ofxOpenButton clicked()?
 *
 * @return void
 **/
void MainWindow::on_ofxOpenButton_clicked() {
    if ( !allCheckBox->isChecked() ) {	// Open one File ...
        _ofxf = OFXFile.get_Handle_to_Infile ( "f", _ofxd );

        ofxLineEdit->setText ( _ofxf );
    } else {								// Open Directory ...
        _ofxd = OFXFile.get_Handle_to_Infile ( "d", _ofxd );

        ofxLineEdit->setText ( _ofxd );
    }
}

/**
 * @brief is allCheckBox clicked?
 *
 * @return void
 **/
void MainWindow::on_allCheckBox_clicked() {
    //    log("blue", "In: on_allCheckBox_clicked()");

    _ifxf = ifxLineEdit->text();

    if ( allCheckBox->isChecked() ) {						// all files to process
        if ( _ifxf == "" )								// if LineEdit is empty ...
            _ifxd = IFXFile.get_Handle_to_Infile ( "d", _ifxd );	// OpenDir Dialog
        else
            _ifxd = IFXFile.get_ifxpath ( _ifxf );

        _ofxd = OFXFile.get_ofxpath ( _ifxf );

        // update UI
        ifxLabel->setText ( trUtf8 ( "Alle IFX Dateien im Verzeichnis" ) );
        ifxLineEdit->setText ( _ifxd );
        ofxLineEdit->setText ( _ofxd );
    } else {											// one File to process
        if ( _ifxf == "" || !IFXFile.is_dir ( _ifxf ) )	// if LineEdit is empty or directory ...
            _ifxf = IFXFile.get_Handle_to_Infile ( "f", _ifxd );	// OpenFile Dialog

        _ofxf = OFXFile.get_ofxfullFileName ( _ifxf );

        // update UI
        ifxLabel->setText ( "IFX Datei" );
        ifxLineEdit->setText ( _ifxf );
        ofxLineEdit->setText ( _ofxf );
    }
}

/**
 * @brief start processing
 *
 * @return int
 **/
int MainWindow::process() {
    //	log("blue", "In: process()");

    _ifxf = ifxLineEdit->text();
    _ofxf = ofxLineEdit->text();
    QFileInfo fInfo(_ofxf);
    _ofxd = fInfo.absolutePath();

    QDir workDir ( _ifxf );

    // Process Directory
    if ( workDir.exists() == true ) {
        processDirectory ( _ifxf );
    }
    // Process one File
    else if ( !workDir.exists() ) {
        processFile ( _ifxf );
    }

    return 0;
}

/**
 * @brief Process all IFX Files in dirName
 *
 * @param dirName const QString: Directory to process
 * @return void
 **/
void MainWindow::processDirectory ( const QString& dirName ) {
    QDir workDir ( dirName );

    //    log ( "blue", "InFile is: Directory" );
    //    log ( "blue", "Directory is: " + dirName );
    QStringList fileList = workDir.entryList ( QStringList ( "*.csv" ) );

    progressBar->setValue ( 0 );
    progressBar->setMaximum ( fileList.size() );

    for ( int i=0; i<fileList.size(); i++ ) {
        log ( "black", QString::number ( i+1 ) +  ": " + fileList.at ( i ) );
        progressBar->setValue ( i+1 );
        processFile ( dirName + "/" + fileList.at ( i ) );
    }
    log ( "black", QString::number ( fileList.size() ) + " Dateien bearbeitet.\n" );
}

/**
 * @brief Process IFX File fileName
 *
 * @param fileName const QString: IFX File to process
 * @return int
 **/
int MainWindow::processFile ( const QString& fileName ) {
    //	log("blue", "In: processFile()");

    log ( "black", "***** " + IFXFile.get_ifxFileName ( fileName ) + " *****" );
    QFile infile ( fileName );
    QFileInfo tmp( infile );
    QDir outdir ( _ofxd );
    _ifxd = IFXFile.get_ifxpath(fileName);
    QFile outfile ( _ofxd + "/" + tmp.baseName() + ".ofx");
    //    QTextStream stream ( &infile );
    //    QString line;
    QStringList start_end;

    log ("blue", "infile: " + fileName);
    log ("blue", "indir: " + IFXFile.get_ifxpath(fileName));
    log ("blue", "outfile: " + _ofxd + "/" + tmp.baseName() + ".ofx");
    log ("blue", "outdir: " + _ofxd);

    // Process one File
    if ( !infile.exists() ) {
        log ( "red", trUtf8 ( "Ooops: Datei existiert nicht." ) );
        return 110;
    } else if ( !infile.open ( QFile::ReadOnly | QFile::Text ) ) {
        log ( "red", trUtf8 ( "Ooops: Datei nicht lesbar." ) );
        return 120;
    }

    if ( !outdir.exists() ) {
        outdir.mkpath(_ofxd);
        log("black", "OFX dir created!\n");
    }

    // get values from standard filename (has to be: KTNR_[DDA|CCA]*.csv)
    acctid = IFXFile.get_ifxbaseName(fileName).split("_").value(0);
    accttype = IFXFile.get_ifxbaseName(fileName).split("_").value(1);

//    bool ok;
//    acctid.toInt(&ok);
//    if(!ok) {
//        Ui::SettingsDlg ui;
//        QDialog *settingsDlg = new QDialog;
//        ui.setupUi(settingsDlg);
//        settingsDlg->show();
//    }

    //loadSettings(acctid);

    ifx.AcctType = accttype;	// DepAcctRec.AcctType
    ifx.AcctId = acctid;	// DepAcctRec.AcctId
    ifx.AcctCur = acctcur;	// DepAcctRec.AcctCur
    //    ifx.AcctOwner = acctowner;// DepAcctRec.Memo

    log ( "grey", "Acct EffDt: " + QDate::currentDate().toString() );
    log ( "grey", "Acct AcctType: " + ifx.AcctType );
    log ( "grey", "Acct AcctId: " + ifx.AcctId );
    log ( "grey", "Acct AcctCur: " + ifx.AcctCur );
    //    log ( "grey", "Acct AcctOwner: " + ifx.AcctOwner );

    // dismiss header line in csv file
    infile.readLine();

    int i = 0;
    while(!infile.atEnd())
    {
        bool done = false;
        QString inputline = infile.readLine();
        while(!done) {
            if (inputline.at(inputline.size() -2) != ';') {
                inputline.append(infile.readLine());
                done = false;
            }
            else
                done = true;
        }

        strings = inputline.split(";");
        if ( ifx.AcctType == "DDA" ) {
            effdt = strings.value(1);
            acctcur = strings.value(4);
            ifx.TrnMemo << strings.value(2).simplified();
            ifx.TrnData << strings.value(6).simplified();

            QString tmptime = strings.value(1);
            ifx.PostedDt << toOfxTime( tmptime );

            start_end << ifx.PostedDt;	// for DTSTART and DTEND
            ifx.CurAmt << strings.value(5).replace(QString ( "." ), QString ( "" )).
                                                   replace(QString ( "," ), QString ( "." ) );
        }
        else if ( ifx.AcctType == "CCA" ) {
            effdt = strings.value(0);   // FIXME:
            acctcur = "EUR";
            ifx.TrnMemo << strings.value(2).simplified();
            ifx.TrnData << strings.value(2).simplified();

            QString tmptime = strings.value(1);
            ifx.PostedDt << toOfxTime( tmptime );

            start_end << ifx.PostedDt;	// for DTSTART and DTEND
            ifx.CurAmt << strings.value(4).split(" ").value(0).replace(QString ( "," ), QString ( "." ));

        }

        // Calculate md5 hash -> FitId
        QString hashstr;
        hashstr.append ( ifx.PostedDt.at(i) );
        hashstr.append ( ifx.CurAmt.at(i) );
        hashstr.append ( ifx.TrnMemo.at(i) );
        QByteArray hash = QCryptographicHash::hash ( hashstr.toUtf8(),
                                                     QCryptographicHash::Md5 );
        ifx.FitId << hash.toHex();

        qDebug() << "----------";
        qDebug() << "i:" << i;
        qDebug() << "Trn at: " + ifx.PostedDt.at(i);
        qDebug() << "Trn Amt: " + ifx.CurAmt.at(i);
        qDebug() << "Trn Memo: " + ifx.TrnMemo.at(i);
        qDebug() << "MD5 Hash: " + ifx.FitId.at(i);

        log ( "black", "----------" );
        log ( "blue", "i: " + QString::number(i));
        //		log ( "blue", "j: " + QString::number(j));
        log ( "grey", "Trn at: " + ifx.PostedDt.at(i) );
        log ( "grey", "Trn Amt: " + ifx.CurAmt.at(i) );
        log ( "grey", "Trn Memo: " + ifx.TrnMemo.at(i) );
        log ( "grey", "MD5 Hash: " +ifx.FitId.at(i) );
        log ( "grey", "Trn Data: " + ifx.TrnData.at(i) );

        i++;
    }

    start_end.sort();
    ifx.DtStart = start_end.at(0);
    ifx.DtEnd = start_end.at(start_end.size()-1);

    //    // creating ofx structure in memory
    ofxdoc = writeOfxBase();
    //}

    //QString xml = ofxdoc.toString();
    if ( !outfile.open(QFile::WriteOnly)) {
        QMessageBox::warning( this, "Speichern", "Speichern fehlgeschlagen." );
        outfile.close();
        return -110;
    }

    // write the ofx structure to outfile
    QTextStream filestream( &outfile );
    filestream << ofxdoc.toString();
    outfile.close();
    ofxdoc.clear();

    //log ("blue", "\n" + xml);

    log ( "black", tr ( "\"" ) + IFXFile.get_ifxFileName ( fileName )
          + tr ( "\" bearbeitet.\n" ) );

}

/**
 * @brief Quit app w - w/o starting gnuCash
 *
 * @return void
 **/
void MainWindow::reject() {
    if ( gnucashCheckBox->isChecked() ) {
        if ( gncPath == "null" ) {
            gncPath = QFileDialog::getOpenFileName(
                        this,
                        trUtf8("Pfad zu gnuCash"),
                        QString::null,
                        QString::null);

        }
        QStringList args;
        QProcess *gnuCashProcess = new QProcess(qApp);
        gnuCashProcess->startDetached(gncPath, args);
    }

    saveSettings();

    QDialog::reject();
}

/**
 * @brief writes the OFX structure to memory till BANKTRANLIST
 *
 * @return QDomDocument ofxdox
 **/
QDomDocument MainWindow::writeOfxBase() {
    QDomProcessingInstruction instr = ofxdoc.createProcessingInstruction(
                "xml", "version='1.0' encoding='ISO-8859-15'");
    ofxdoc.appendChild(instr);
    QDomElement ofx_root = ofxdoc.createElement("OFX");
    ofxdoc.appendChild(ofx_root);
    QDomElement signonmsgsrsv1 = ofxdoc.createElement("SIGNONMSGSRSV1");
    ofx_root.appendChild(signonmsgsrsv1);
    QDomElement sonrs = ofxdoc.createElement("SONRS");
    signonmsgsrsv1.appendChild(sonrs);
    QDomElement status = ofxdoc.createElement("STATUS");
    sonrs.appendChild(status);
    QDomElement code = ofxdoc.createElement("CODE");
    status.appendChild(code);
    QDomText text = ofxdoc.createTextNode(ofx.CODE);
    code.appendChild(text);
    QDomElement severity = ofxdoc.createElement("SEVERITY");
    status.appendChild(severity);
    text = ofxdoc.createTextNode(ofx.SEVERITY);
    severity.appendChild(text);
    QDomElement dtserver = ofxdoc.createElement("DTSERVER");
    sonrs.appendChild(dtserver);
    text = ofxdoc.createTextNode(ifx.EffDt + "000000");
    dtserver.appendChild(text);
    QDomElement language = ofxdoc.createElement("LANGUAGE");
    sonrs.appendChild(language);
    text = ofxdoc.createTextNode(ofx.LANGUAGE);
    language.appendChild(text);
    QDomElement bankmsgsrsv1 = ofxdoc.createElement("BANKMSGSRSV1");
    ofx_root.appendChild(bankmsgsrsv1);
    QDomElement stmttrnrs = ofxdoc.createElement("STMTTRNRS");
    bankmsgsrsv1.appendChild(stmttrnrs);
    QDomElement trnuid = ofxdoc.createElement("TRNUID");
    stmttrnrs.appendChild(trnuid);
    text = ofxdoc.createTextNode(ofx.TRNUID);
    trnuid.appendChild(text);
    status = ofxdoc.createElement("STATUS");
    stmttrnrs.appendChild(status);
    code = ofxdoc.createElement("CODE");
    status.appendChild(code);
    text = ofxdoc.createTextNode(ofx.CODE);
    code.appendChild(text);
    severity = ofxdoc.createElement("SEVERITY");
    status.appendChild(severity);
    text = ofxdoc.createTextNode(ofx.SEVERITY);
    severity.appendChild(text);
    QDomElement stmtrs = ofxdoc.createElement("STMTRS");
    stmttrnrs.appendChild(stmtrs);
    QDomElement curdef = ofxdoc.createElement("CURDEF");
    stmtrs.appendChild(curdef);
    text = ofxdoc.createTextNode(ifx.AcctCur);
    curdef.appendChild(text);
    QDomElement bankacctfrom = ofxdoc.createElement("BANKACCTFROM");
    stmtrs.appendChild(bankacctfrom);
    QDomElement bankid = ofxdoc.createElement("BANKID");
    bankacctfrom.appendChild(bankid);
    text = ofxdoc.createTextNode(ofx.BANKID);
    bankid.appendChild(text);
    QDomElement acctid = ofxdoc.createElement("ACCTID");
    bankacctfrom.appendChild(acctid);
    text = ofxdoc.createTextNode(ifx.AcctId);
    acctid.appendChild(text);
    QDomElement accttype = ofxdoc.createElement("ACCTTYPE");
    bankacctfrom.appendChild(accttype);
    text = ofxdoc.createTextNode(ofx.ACCTTYPE);
    accttype.appendChild(text);
    QDomElement banktranlist = ofxdoc.createElement("BANKTRANLIST");
    stmtrs.appendChild(banktranlist);
    QDomElement dtstart = ofxdoc.createElement("DTSTART");
    banktranlist.appendChild(dtstart);
    text = ofxdoc.createTextNode(ifx.DtStart);
    dtstart.appendChild(text);
    QDomElement dtend = ofxdoc.createElement("DTEND");
    banktranlist.appendChild(dtend);
    text = ofxdoc.createTextNode(ifx.DtEnd);
    dtend.appendChild(text);
    for ( int i=0; i<ifx.FitId.size(); i++) {
        QDomElement stmttrn = ofxdoc.createElement("STMTTRN");
        banktranlist.appendChild(stmttrn);
        QDomElement trntype = ofxdoc.createElement("TRNTYPE");
        stmttrn.appendChild(trntype);
        text = ofxdoc.createTextNode(ofx.TRNTYPE);
        trntype.appendChild(text);
        QDomElement dtposted = ofxdoc.createElement("DTPOSTED");
        stmttrn.appendChild(dtposted);
        text = ofxdoc.createTextNode(ifx.PostedDt.at(i));
        dtposted.appendChild(text);
        QDomElement trnamt = ofxdoc.createElement("TRNAMT");
        stmttrn.appendChild(trnamt);
        text = ofxdoc.createTextNode(ifx.CurAmt.at(i));
        trnamt.appendChild(text);
        QDomElement fitid = ofxdoc.createElement("FITID");
        stmttrn.appendChild(fitid);
        text = ofxdoc.createTextNode(ifx.FitId.at(i));
        fitid.appendChild(text);
        QDomElement memo = ofxdoc.createElement("MEMO");
        stmttrn.appendChild(memo);
        text = ofxdoc.createTextNode(ifx.TrnData.at(i));
        memo.appendChild(text);
        QDomElement data = ofxdoc.createElement("NAME");
        stmttrn.appendChild(data);
        text = ofxdoc.createTextNode(ifx.TrnMemo.at(i));
        data.appendChild(text);
    }
    QDomElement ledgerbal = ofxdoc.createElement("LEDGERBAL");
    stmtrs.appendChild(ledgerbal);
    QDomElement balamt = ofxdoc.createElement("BALAMT");
    ledgerbal.appendChild(balamt);
    text = ofxdoc.createTextNode(ofx.BALAMT);
    balamt.appendChild(text);
    QDomElement dtasof = ofxdoc.createElement("DTASOF");
    ledgerbal.appendChild(dtasof);
    text = ofxdoc.createTextNode(ifx.DTASOF);
    dtasof.appendChild(text);
    QDomElement availbal = ofxdoc.createElement("AVAILBAL");
    stmtrs.appendChild(availbal);
    balamt = ofxdoc.createElement("BALAMT");
    availbal.appendChild(balamt);
    text = ofxdoc.createTextNode(ofx.BALAMT);
    balamt.appendChild(text);
    dtasof = ofxdoc.createElement("DTASOF");
    availbal.appendChild(dtasof);
    text = ofxdoc.createTextNode(ifx.DTASOF);
    dtasof.appendChild(text);

    return ofxdoc;
}

/**
 * @brief converts DD.MM.YYYY to YYYY-MM-DD
 *
 * @param tmptime Date in DD.MM.YYYY format
 * @return QString Date in YYYY-MM-DD format
 **/
QString MainWindow::toOfxTime( QString& tmptime ) {
    if (tmptime.contains(".")) {
        QStringList elements = tmptime.split( "." );
        return elements[2].
                append(elements[1]).
                append(elements[0]);
    }
    else if (tmptime.contains("/")) {
        QStringList elements = tmptime.split("/");
        return elements[2].
                append(elements[1]).
                append(elements[0]);
    }
    else
        return "00000000";
}

void MainWindow::settings() {
    QString tmpId;
    QString tmpOwn;
    QString tmpCur;
    QString tmpType;

    Ui::SettingsDlg ui;
    QDialog *settingsDlg = new QDialog;
    ui.setupUi(settingsDlg);

    connect (settingsDlg, SIGNAL(saveMe(QString,
                                        QString,
                                        QString,
                                        QString)),
             this, SLOT(saveSettings(QString,
                                     QString,
                                     QString,
                                     QString)));

    ui.acctComboBox->addItem(acctid);
    settingsDlg->show();
}

/**
 * @brief loads App Settings
 *
 * @return void
 **/
void MainWindow::loadSettings(QString id) {
    QSettings settings(SettingsFile, QSettings::NativeFormat);
    gncPath = settings.value("gncPath", "null").toString();
    //	allCheckBox->setChecked(settings.value("allCheckBox", "false").toBool());
    gnucashCheckBox->setChecked(settings.value("gnucashCheckBox", "false").toBool());
    _ifxd = settings.value("ifxPath", "").toString();
    ifxLineEdit->setText(settings.value("ifxPath", "").toString());
    settings.beginGroup("Accounts");
    settings.beginGroup(id);
    acctid = settings.value("acctid", "").toString();
    accttype = settings.value("accttype", "").toString();
    acctcur = settings.value("acctcurrency", "").toString();
}

/**
 * @brief loads App Settings
 *
 * @return void
 **/
void MainWindow::loadSettings() {
    QSettings settings(SettingsFile, QSettings::NativeFormat);
    gncPath = settings.value("gncPath", "null").toString();
    //	allCheckBox->setChecked(settings.value("allCheckBox", "false").toBool());
    gnucashCheckBox->setChecked(settings.value("gnucashCheckBox", "false").toBool());
    _ifxd = settings.value("ifxPath", "").toString();
    ifxLineEdit->setText(settings.value("ifxPath", "").toString());
}


/**
 * @brief saves App Settings
 *
 * @return void
 **/
void MainWindow::saveSettings() {
    QSettings settings(SettingsFile, QSettings::NativeFormat);
    settings.setValue("gncPath", gncPath);
    settings.setValue("allCheckBox", allCheckBox->isChecked());
    settings.setValue("gnucashCheckBox", gnucashCheckBox->isChecked());
    settings.setValue("ifxPath", _ifxd);
    settings.beginGroup("Accounts");
    settings.beginGroup(acctid);
    settings.setValue("acctid", acctid);
    settings.setValue("accttype", accttype);
    settings.setValue("acctcurrency", acctcur);
    settings.endGroup();
    settings.endGroup();
}

/**
 * @brief saves App Settings
 *
 * @return void
 **/
void MainWindow::saveSettings(QString id,QString type, QString cur) {
    QSettings settings(SettingsFile, QSettings::NativeFormat);
    settings.setValue("gncPath", gncPath);
    settings.setValue("allCheckBox", allCheckBox->isChecked());
    settings.setValue("gnucashCheckBox", gnucashCheckBox->isChecked());
    settings.setValue("ifxPath", _ifxd);
    settings.beginGroup("Accounts");
    settings.beginGroup(id);
    settings.setValue("acctid", id);
    settings.setValue("accttype", type);
    settings.setValue("acctcurrency", cur);
    settings.endGroup();
    settings.endGroup();
}


/**
 * @brief log Text to LogTextBrowser
 *
 * @param color const QString: color of Log Entry
 * @param message const QString: Message to display
 * @return void
 **/
void MainWindow::log ( const QString& color, const QString& message ) {
    logTextBrowser->setTextColor ( color );
    logTextBrowser->append ( message );
}

